#ifndef _QSPIFLASH_H_
#define _QSPIFLASH_H_

#include "oc_rsrc_cfg.h"
#include "quadspi.h"

/* W25Q64基本信息 */
#define QSPI_W25Q64JV_FLASH_SIZE_EXP 23                      /* Flash大小，2^23 = 8MB*/
#define QSPI_W25Q64JV_SECTOR_SIZE    (4 * 1024)              /* 扇区大小，4KB */
#define QSPI_W25Q64JV_PAGE_SIZE      256                     /* 页大小，256字节 */
#define QSPI_W25Q64JV_END_ADDR        (1 << QSPI_FLASH_SIZE) /* 末尾地址 */
#define QSPI_W25Q64JV_FLASH_SIZES    8 * 1024 * 1024         /* Flash大小，2^25 = 32MB*/
#define QSPI_W25Q64JV_FLASH_ID       0xEF4017

/* W25Q64相关命令 */
#define QSPI_W25Q64JV_DEVICE_ID              0x9F                   /* 读取器件ID */
#define QSPI_W25Q64JV_STATUS_REG1            0x05                   /* 读取状态1命令 */
#define QSPI_W25Q64JV_ERASE_SECTOR           0x20                   /* 扇区擦除命令 */
#define QSPI_W25Q64JV_WRITE_ENABLE           0x06                   /* 写使能指令 */
/*
 * The Quad Enable QE bit is set to 1 by default in the factory, therefore the device supports Standard/Dual
 * SPI as well as Quad SPI after power on. This bit cannot be reset to 0.
 */
#define QSPI_W25Q64JV_FAST_IO_READ_4LINE     0xEB                   /* 4线快速读取命令 */
#define QSPI_W25Q64JV_PAGE_PROGRAM_1LINE     0x02                   /* 单线写入命令 */
#define QSPI_W25Q64JV_PAGE_PROGRAM_4LINE     0x32                   /* 4线写入命令 */

/* W25Q64 写的方式选择 */ 
//#define QSPI_W25Q64JV_SELECT_PROGRAME_1LINE

/* spiflash 芯片相关特性 */
typedef struct QSPIFLASH_ATTR_STR
{
    uint32_t chip_id;            /* 芯片ID */
    char     chip_name[16];      /* 芯片型号字符串，主要用于显示 */
    uint32_t total_size;         /* 总容量 */
    uint32_t bank_size;          /* 块大小 */
    uint16_t sector_size;        /* 扇区大小 */
    uint16_t page_size;          /* 页大小 */
} qspiflash_attr, *qspiflash_attr_t;

/* spiflash 硬件操作 for mboot */
typedef struct qspiflash_op_for_mboot_str
{
    hw_addr_attr * (*take_free_space)(uint32_t size);        /* 分配一片空间 */
    HW_STATUS (*erase_space)(uint32_t addr);                 /* 擦除这片空间 */
    int (*put_data)(hw_buf_attr * buf_attr, uint32_t addr);  /* 写数据 */
    hw_buf_attr * (*get_data)(uint32_t addr, uint16_t nbr);  /* 读数据 */
    int (*memory_mapped)(void);                          /* 内存映射 */
} qspiflash_op_for_mboot;

/* qspi 初始化 */
int qspiflash_init(void);

/* 注册操作函数接口 */
qspiflash_op_for_mboot *qspiflash_op_for_mboot_register(void);

#endif
